<template>
  <div class="screen-shot">
    <align-line></align-line>
    <ruler :isShowReferLine="referLine.enable" :lang="rulerOption.lang"
      :thick="rulerOption.thick" :scale="rulerOption.scale"
      :width="rulerOption.width" :height="rulerOption.height"
      :startX="rulerOption.startX" :startY="rulerOption.startY"
      :horLineArr="rulerOption.lines.h" :verLineArr="rulerOption.lines.v"
      :cornerActive="rulerOption.cornerActive" :palette="rulerOption.palette"
      @onCornerClick="handleRuleCornerClick" @handleLine="handleLine"></ruler>
    <!-- 整体背景 -->
    <div @wheel="handleScreenWheel" @scroll.passive="handleScreenScroll"
      class="screens" id="screens" ref="screens">
      <!-- 蓝色背景 -->
      <div :style="canvasStyle">
        <div id="comps-map" :style="canvasMapStyle">
          <div class="canvas-map-layout-item" v-for="items in components"
            :key="items.id" :style="canvasMapLayoutItem(items)"></div>
        </div>
        <div id="canvas-comps" class="canvas-panel" :style="canvasCompsStyle"
          @contextmenu="handleContextMenu" @mousedown="handleMouseDown"
          @drop="handleCompDrop($event)" @dragover="handleCompDragOver($event)"
          @mouseup="deselectCurComponent($event)">
          <canvas-editor></canvas-editor>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import {
  computed,
  defineComponent,
  nextTick,
  ref,
  watch,
  reactive,
  watchEffect,
  defineAsyncComponent,
  onMounted,
  onUnmounted,
} from "vue";
import { useDesignStore } from "../../../../../store/design";
import alignLine from "./align-line.vue";
import ruler from "./ruler/ruler.vue";
import { SketchRuleOption } from "./../../../../../utils/constant";
import { UUID3 } from "../../../../../utils/uuid";
import { emitter } from "../../../../../utils/emitter";
import { createComponent } from "../../../../van/libs";
const CanvasEditor = defineAsyncComponent(() =>
  import("./canvas-editor/index.vue")
);
export default defineComponent({
  name: "canvas-main",
  components: {
    alignLine,
    ruler,
    CanvasEditor,
  },
  setup() {
    const screens = ref();
    const designStore = useDesignStore();
    const pageConfig = computed(() => designStore.pageConfig);
    const referLine = computed(() => designStore.referLine);
    const editor = computed(() => designStore.editor);
    const isClickComponent = computed(() => designStore.isClickComponent);
    const components = computed(() => designStore.pageComponents);
    const rulerOption = reactive(SketchRuleOption);
    const handleRuleCornerClick = () => {
      designStore.setReferLineShow();
      rulerOption.cornerActive = !rulerOption.cornerActive;
    };
    const handleLine = (lines) => {
      rulerOption.lines = lines;
    };
    const handleScreenWheel = (e) => {
      if (e.ctrlKey || e.metaKey) {
        e.preventDefault();
        let scaleValue = pageConfig.value.scale;
        const nextScale = parseFloat(
          Math.max(0.2, scaleValue - e.deltaY / 500).toFixed(2)
        );
        if (nextScale >= 2) {
          return;
        }
        designStore.setScale(nextScale);
      }
      nextTick(() => {
        handleScreenScroll();
      });
    };
    const handleScreenScroll = () => {
      const screensRect = document
        .querySelector("#screens")
        .getBoundingClientRect();
      const canvasRect = document
        .querySelector("#canvas-comps")
        .getBoundingClientRect();
      // // 标尺开始的刻度
      const startX =
        (screensRect.left + rulerOption.thick - canvasRect.left) /
        pageConfig.value.scale;
      const startY =
        (screensRect.top + rulerOption.thick - canvasRect.top) /
        pageConfig.value.scale;
      rulerOption.startX = startX >> 0;
      rulerOption.startY = startY >> 0;
      rulerOption.scale = pageConfig.value.scale;
    };
    const canvasStyle = ref({});
    watchEffect(() => {
      const screens = document.getElementById("screens");
      const screensHeight = screens ? screens.offsetHeight : 0;
      const screensWidth = screens ? screens.offsetWidth : 0;
      let canvasWidth = "0px";
      let canvasHeight = "0px";
      if (
        (screensHeight &&
          screensHeight >
            pageConfig.value.height * pageConfig.value.scale + 50) ||
        (screensWidth &&
          screensWidth > pageConfig.value.width * pageConfig.value.scale + 50)
      ) {
        canvasHeight = `${pageConfig.value.height * pageConfig.value.scale}px`;
        canvasWidth = `${pageConfig.value.width * pageConfig.value.scale}px`;
      } else {
        canvasHeight = `${
          (pageConfig.value.height + 200) * pageConfig.value.scale
        }px`;
        canvasWidth = `${
          (pageConfig.value.width + 200) * pageConfig.value.scale
        }px`;
      }
      canvasStyle.value = {
        position: "absolute",
        top: 48 + "px",
        left: 48 + "px",
        width: canvasWidth,
        height: canvasHeight,
      };
    });
    watch(
      () => pageConfig.value.scale,
      (val) => {
        rulerOption.scale = val;
        nextTick(() => {
          handleScreenScroll();
        });
      },
      { deep: true }
    );
    const canvasMapStyle = computed(() => {
      return {
        backgroundImage: `url(${pageConfig.value.bgImage})`,
        height: `${pageConfig.value.height * pageConfig.value.scale}px`,
        width: `${pageConfig.value.width * pageConfig.value.scale}px`,
        zIndex: -99,
      };
    });
    const canvasCompsStyle = computed(() => {
      return {
        position: "absolute",
        backgroundColor: pageConfig.value.bgColor,
        backgroundImage: `url(${pageConfig.value.bgImage})`,
        height: `${pageConfig.value.height}px`,
        width: `${pageConfig.value.width}px`,
        transform: `scale(${pageConfig.value.scale}) translate(0px, 0px)`,
      };
    });
    const canvasMapLayoutItem = (com) => {
      return {
        position: "absolute",
        width: `${com.attr.width * pageConfig.value.scale}px`,
        height: `${com.attr.height * pageConfig.value.scale}px`,
        top: "0px",
        left: "0px",
        transform: `translate(${com.attr.left * pageConfig.value.scale}px, ${
          com.attr.top * pageConfig.value.scale
        }px)`,
      };
    };
    const handleCompDrop = async (e) => {
      e.preventDefault();
      e.stopPropagation();
      const comString = e.dataTransfer.getData("dragCom");
      if (!comString) {
        return;
      }
      const com = JSON.parse(comString);
      if (!editor.value) {
        await designStore.getEditor();
      }
      const rectInfo = editor.value.getBoundingClientRect();
      if (com.type) {
        // const componentSrc = comLibs
        const component = await createComponent(com);
        component.attr.top = (e.clientY - rectInfo.y) / pageConfig.value.scale;
        component.attr.left = (e.clientX - rectInfo.x) / pageConfig.value.scale;
        // 組件id 十位構成
        component.id = UUID3(10);
        designStore.addComponent({ component });
        designStore.addSnapshot();
      }
    };
    const handleCompDragOver = (e) => {
      e.preventDefault();
      e.dataTransfer.dropEffect = "copy";
    };
    const deselectCurComponent = (e) => {
      if (!isClickComponent.value) {
        designStore.setCurComponent({ component: null, index: null });
      }
      if (e.button != 2) {
        designStore.hideContextMenu();
      }
    };
    const handleMouseDown = (e) => {
      e.stopPropagation();
      designStore.setClickComponentStatus(false);
      designStore.setInEditorStatus(true);
    };
    onMounted(() => {
      rulerOption.scale = pageConfig.value.scale;
      emitter.on("screenSroll", () => {
        handleScreenScroll();
      });
    });
    onUnmounted(() => {});
    return {
      screens,
      editor,
      pageConfig,
      components,
      canvasStyle,
      canvasMapStyle,
      canvasCompsStyle,
      isClickComponent,
      referLine,
      rulerOption,
      canvasMapLayoutItem,
      handleRuleCornerClick,
      handleLine,
      handleScreenWheel,
      handleScreenScroll,
      handleCompDragOver,
      handleCompDrop,
      deselectCurComponent,
      handleMouseDown,
    };
  },
});
</script>

<style lang="less" scoped>
.screen-shot {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  position: relative;

  .screens {
    position: relative;
    background-image: url("https://fengnull.gitee.io/picture_house/design/bg-design.png");
    background-repeat: repeat;
    overflow: auto;
    height: 100%;
    width: 100%;
  }
  #comps-map {
    position: absolute;
  }
  #canvas-comps {
    position: absolute;
    transform-origin: 0 0;
    box-shadow: #00000080 0 0 30px;
  }
}
</style>
